package com.hzy.bootstrap;

import com.hzy.api.HttpServerVerticle;
import com.hzy.service.document.MySQLDocumentVerticle;
import com.hzy.service.ollama.OllamaVerticle;
import com.hzy.service.rag.RAGVerticle;
import com.hzy.utils.DbUtils;
import com.hzy.utils.RedisUtil;
import io.vertx.config.ConfigRetriever;
import io.vertx.config.ConfigRetrieverOptions;
import io.vertx.config.ConfigStoreOptions;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.impl.future.CompositeFutureImpl;
import io.vertx.core.json.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MainVerticle extends AbstractVerticle {

    private static final Logger LOGGER = LoggerFactory.getLogger(MainVerticle.class);

    private void initializer(JsonObject config) {
        DbUtils.initializer(vertx);
        RedisUtil.initialize(vertx, config);
    }

    @Override
    public void start(Promise<Void> startPromise) {
        // 配置 Vert.x 配置检索器
        ConfigStoreOptions fileStore = new ConfigStoreOptions()
                .setType("file")
                .setFormat("json")
                .setConfig(new JsonObject().put("path", "conf/config.json"));

        ConfigRetrieverOptions options = new ConfigRetrieverOptions().addStore(fileStore);
        ConfigRetriever retriever = ConfigRetriever.create(vertx, options);
        LOGGER.info("Starting MainVerticle...");
        retriever.getConfig()
                .onSuccess(config -> {
                    vertx.sharedData().getLocalMap("config").put("appConfig", config);

                    initializer(config);

                    Future<String> documentDeployment = vertx.deployVerticle(MySQLDocumentVerticle.class.getName(), new DeploymentOptions().setInstances(1));
                    Future<String> ollamaDeployment = vertx.deployVerticle(OllamaVerticle.class.getName(), new DeploymentOptions().setInstances(1));

                    CompositeFutureImpl.all(documentDeployment, ollamaDeployment)
                            .compose(ar -> {
                                LOGGER.info("DocumentVerticle and OllamaVerticle deployed successfully.");
                                return vertx.deployVerticle(RAGVerticle.class.getName(), new DeploymentOptions().setInstances(5));
                            })
                            .compose(ragId -> {
                                LOGGER.info("RAGVerticle deployed successfully. ID: {}", ragId);
                                return vertx.deployVerticle(HttpServerVerticle.class.getName(), new DeploymentOptions().setInstances(10));
                            })
                            .onSuccess(apiId -> {
                                LOGGER.info("HttpServerVerticle deployed successfully. ID: {}", apiId);
                                startPromise.complete();
                            })
                            .onFailure(throwable -> {
                                LOGGER.error("Failed to deploy one or more Verticals", throwable);
                                startPromise.fail(throwable);
                                vertx.close();
                            });
                })
                .onFailure(throwable -> {
                    LOGGER.error("Failed to load configuration", throwable);
                    startPromise.fail(throwable);
                    vertx.close();
                });
    }

    @Override
    public void stop(Promise<Void> stopPromise) {
        LOGGER.info("Stopping MainVerticle...");
        stopPromise.complete();
    }
}